# coding=utf-8
import os
import time

import allure
import pytest,jsonpath
from common.assert_operator import Pact, string_assert, dict_assert
from common.db import sql
from common.logger import Logger
from common.read_yaml import ReadYaml_By_Root_Dict, ReadYaml
from common.verification import Verification
from common.utils import Utils

string_assert = string_assert() # 字符串校验类
pact = Pact() # 契约校验类
execute_sql = sql() # sql集合
utils = Utils()
verification = Verification()
data = ReadYaml_By_Root_Dict("case/02_approve_submit_test/02_1_FinishNode_NoConfirm.yml").get_yaml_data()  # 读取数据

@allure.feature('审批提交，不明确路径')  # 测试报告显示测试功能
class Test_02_1_FinishNode_NoConfirm():

    # 获取yml文件中[审批不明确路径_确认路径责任人]的数据参数
    approve_process_params = data['审批不明确路径_确认路径责任人']
    # 获取yml的title，并作为ids的值传给用例
    ids_list = jsonpath.jsonpath(approve_process_params,"$[*][0]")
    @pytest.mark.parametrize("title, param, expect", approve_process_params,ids=ids_list)
    def test_FinishNode_NoConfirm_Open_Path(self, user_login, title, param, expect):
        Logger.info("*************** {}开始执行用例 ***************".format(title))
        allure.dynamic.description(f"{param['description']}")  # # 动态解析用例描述在测试报告中展示
        user,process_name = param['user'],param['process_name']
        DBNodeVerify, MessageVerify, ConfirmPathVerify = '数据库校验', '消息校验','确认路径校验'
        contract_format = pact.approve_pact_format()
        main = user_login.goto_Approve_Process(user)    # 登录到审批类实例
        process_instance_resp = main.open_process_instance(process_name)   # 通过流程名称打开流程实例
        process_params = main.get_key_by_process_instance(process_instance_resp,'params')['params']  # 打开流程响应的Params
        proc_id = jsonpath.jsonpath(process_params,'$.proc_id')[0] # 当前流程的proc_id
        node_id = jsonpath.jsonpath(process_params,'$.node_id')[0] # 当前流程的node_id
        package_id = jsonpath.jsonpath(process_params,'$.package_id')[0] # 当前流程的package_id
        confirm_path_resp = main.approve_confirm_path(param, process_instance_resp) # 确认路径
        response = main.approve_submit(param, process_instance_resp)    # 提交审批
        # 确认路径及审批后校验
        verification.after_approve(process_name, response,
                                   expect, contract_format, DBNodeVerify, MessageVerify,
                                   confirm_path_resp=confirm_path_resp, confirm_path_verify=ConfirmPathVerify)
        Logger.info("*************** 【{}】审批撤回 ***************".format(process_name))
        contract_format = pact.approval_withdraw_pact_format()  # 审批撤回契约格式
        DBNodeVerify, MessageVerify,TodoListVerifiy = '撤回后数据库校验', '撤回后消息校验','撤回后待办列表校验'
        # 使用已审批的节点信息打开流程
        process_instance = main.open_process_instance(node_id=node_id, proc_id=proc_id, package_id=package_id)
        # 撤回审批
        withdraw_resp = main.approval_withdraw(process_instance, param['process_name'], '审批撤回')
        # 撤回后校验
        verification.after_approve(process_name, withdraw_resp,
                                   expect, contract_format, DBNodeVerify, MessageVerify,todo_list=TodoListVerifiy)
        Logger.info("*************** {}结束执行用例 ***************".format(title))

    # 获取yml文件中[审批不明确路径_选择分支]的数据参数
    approve_process_params = data['审批不明确路径_选择分支']
    # 获取yml的title，并作为ids的值传给用例
    ids_list = jsonpath.jsonpath(approve_process_params,"$[*][0]")
    @pytest.mark.parametrize("title, param, expect", approve_process_params,ids=ids_list)
    def test_FinishNode_NoConfirm_Choose_Branch(self, user_login, title, param, expect):
        utils.mark_skip_case(param, 'bug')  # 存在需要跳过的用例
        Logger.info("*************** {}开始执行用例 ***************".format(title))
        allure.dynamic.description(f"{param['description']}")  # # 动态解析用例描述在测试报告中展示
        user,process_name = param['user'],param['process_name']
        ConfirmPath,ChoosePath = "确认路径校验", "选择分支校验"
        main = user_login.goto_Approve_Process(user)    # 登录到审批类实例
        process_instance_resp = main.open_process_instance(process_name)   # 通过流程名称打开流程实例
        confirm_path_resp = main.approve_confirm_path(param, process_instance_resp)
        path = utils.pack_confirm_steps_field(confirm_path_resp.json(),['.tag'],ConfirmPath)    # 弹出确认路径
        dict_assert(expect[ConfirmPath], path)  # 审批确认路径校验
        choose_branch_resp = main.choose_branch_return(param, process_instance_resp)
        choose_branch = utils.pack_confirm_steps_field(choose_branch_resp.json(),['.tag'],ChoosePath)   # 选择分支后路径
        dict_assert(expect[ChoosePath], choose_branch)  # 审批确认路径校验

    # 获取yml文件中[审批不明确路径_不确认路径责任人]的数据参数
    approve_process_params = data['审批不明确路径_不确认路径责任人']
    # 获取yml的title，并作为ids的值传给用例
    ids_list = jsonpath.jsonpath(approve_process_params,"$[*][0]")
    @pytest.mark.parametrize("title, param, expect", approve_process_params,ids=ids_list)
    def test_FinishNode_NoConfirm_Clear_Path(self, user_login, title, param, expect):
        utils.mark_skip_case(param, 'bug')  # 存在需要跳过的用例
        Logger.info("*************** {}开始执行用例 ***************".format(title))
        allure.dynamic.description(f"{param['description']}")  # # 动态解析用例描述在测试报告中展示
        user,process_name = param['user'],param['process_name']
        DBNodeVerify, MessageVerify = '数据库校验', '消息校验'
        contract_format = pact.approve_pact_format()
        main = user_login.goto_Approve_Process(user)    # 登录到审批类实例
        process_instance_resp = main.open_process_instance(process_name)   # 通过流程名称打开流程实例
        process_params = main.get_key_by_process_instance(process_instance_resp,'params')['params']  # 打开流程响应的Params
        proc_id = jsonpath.jsonpath(process_params,'$.proc_id')[0] # 当前流程的proc_id
        node_id = jsonpath.jsonpath(process_params,'$.node_id')[0] # 当前流程的node_id
        package_id = jsonpath.jsonpath(process_params,'$.package_id')[0] # 当前流程的package_id
        response = main.approve_submit(param, process_instance_resp)    # 提交审批
        # 审批后校验
        verification.after_approve(process_name,response,expect,contract_format,DBNodeVerify,MessageVerify)
        Logger.info("*************** 【{}】审批撤回 ***************".format(process_name))
        contract_format = pact.approval_withdraw_pact_format()  # 审批撤回契约格式
        DBNodeVerify, MessageVerify, TodoListVerifiy = '撤回后数据库校验', '撤回后消息校验', '撤回后待办列表校验'
        # 使用已审批的节点信息打开流程
        process_instance = main.open_process_instance(node_id=node_id, proc_id=proc_id, package_id=package_id)
        # 撤回审批
        withdraw_resp = main.approval_withdraw(process_instance, param['process_name'], '审批撤回')
        # 审批撤回后校验
        verification.after_approve(process_name, withdraw_resp,
                                   expect, contract_format, DBNodeVerify, MessageVerify, todo_list=TodoListVerifiy)
        Logger.info("*************** {}结束执行用例 ***************".format(title))


# 获取yml文件中[审批不明确路径_跳过不可撤回]的数据参数
    approve_process_params = data['审批不明确路径_跳过不可撤回']
    # 获取yml的title，并作为ids的值传给用例
    ids_list = jsonpath.jsonpath(approve_process_params,"$[*][0]")
    @pytest.mark.parametrize("title, param, expect", approve_process_params,ids=ids_list)
    def test_FinishNode_NoConfirm_Skip(self, user_login, title, param, expect):
        utils.mark_skip_case(param, 'bug')  # 存在需要跳过的用例
        Logger.info("*************** {}开始执行用例 ***************".format(title))
        allure.dynamic.description(f"{param['description']}")  # # 动态解析用例描述在测试报告中展示
        user,process_name = param['user'],param['process_name']
        DBNodeVerify, MessageVerify = '数据库校验', '消息校验'
        contract_format = pact.approve_pact_format()
        main = user_login.goto_Approve_Process(user)    # 登录到审批类实例
        process_instance_resp = main.open_process_instance(process_name)   # 通过流程名称打开流程实例
        process_params = main.get_key_by_process_instance(process_instance_resp,'params')['params']  # 打开流程响应的Params
        proc_id = jsonpath.jsonpath(process_params,'$.proc_id')[0] # 当前流程的proc_id
        node_id = jsonpath.jsonpath(process_params,'$.node_id')[0] # 当前流程的node_id
        package_id = jsonpath.jsonpath(process_params,'$.package_id')[0] # 当前流程的package_id
        response = main.approve_submit(param, process_instance_resp)    # 提交审批
        # 审批后校验
        verification.after_approve(process_name, response, expect, contract_format, DBNodeVerify, MessageVerify)
        # 使用已审批的节点信息打开流程
        process_instance = main.open_process_instance(node_id=node_id, proc_id=proc_id, package_id=package_id)
        # 撤回审批
        withdraw_resp = main.approval_withdraw(process_instance, param['process_name'], '审批撤回')
        dict_assert(expect['撤回异常响应'],withdraw_resp.json())
        Logger.info("*************** {}结束执行用例 ***************".format(title))
